package com.jacobson.huobi.utils

import com.jacobson.core.widget.logger.LoggerFactory
import com.jacobson.huobi.common.constants.AlarmTypeConstant
import com.jacobson.huobi.common.constants.PriorityNumConstant
import com.jacobson.huobi.common.constants.PrioritySetConstant
import com.jacobson.huobi.entities.SymbolInfo
import java.lang.Exception

class ComparableHelper : Comparator<SymbolInfo> {
    private val logger = LoggerFactory.getLogger("GlobalError")

    override fun compare(o1: SymbolInfo, o2: SymbolInfo): Int {
        try {
            if (o1.realtimePrimary && !o2.realtimePrimary) {
                return -1
            } else if (!o1.realtimePrimary && o2.realtimePrimary) {
                return 1
            } else {
                if (comparePriority(o1, o2) >= 1) {
                    return 1
                } else if (comparePriority(o1, o2) <= -1) {
                    return -1
                } else {

                    if ((AlarmTypeConstant.getDescByValue(o1.alarmH1.type) == AlarmTypeConstant.DESC_START || AlarmTypeConstant.getDescByValue(
                            o1.alarmH1.type
                        ) == AlarmTypeConstant.DESC_STAND)
                        && (AlarmTypeConstant.getDescByValue(o2.alarmH1.type) != AlarmTypeConstant.DESC_START && AlarmTypeConstant.getDescByValue(
                            o2.alarmH1.type
                        ) != AlarmTypeConstant.DESC_STAND)
                    ) {
                        return -1
                    } else if ((AlarmTypeConstant.getDescByValue(o2.alarmH1.type) == AlarmTypeConstant.DESC_START || AlarmTypeConstant.getDescByValue(
                            o2.alarmH1.type
                        ) == AlarmTypeConstant.DESC_STAND)
                        && (AlarmTypeConstant.getDescByValue(o1.alarmH1.type) != AlarmTypeConstant.DESC_START && AlarmTypeConstant.getDescByValue(
                            o1.alarmH1.type
                        ) != AlarmTypeConstant.DESC_STAND)
                    ) {
                        return 1
                    } else {
                        //2.破线
                        if (AlarmTypeConstant.getDescByValue(o1.alarmH1.type) == AlarmTypeConstant.DESC_BREAK && AlarmTypeConstant.getDescByValue(
                                o2.alarmH1.type
                            ) != AlarmTypeConstant.DESC_BREAK
                        ) {
                            return -1
                        } else if (AlarmTypeConstant.getDescByValue(o1.alarmH1.type) != AlarmTypeConstant.DESC_BREAK && AlarmTypeConstant.getDescByValue(
                                o2.alarmH1.type
                            ) == AlarmTypeConstant.DESC_BREAK
                        ) {
                            return 1
                        } else {
//                        if (comparePriorityLevel(o1, o2) >= 1) {
//                            return 1
//                        }else if (comparePriorityLevel(o1, o2) <= -1){
//                            return -1
//                        }else {
                            return (o2.alarmH1.dateTime - o1.alarmH1.dateTime).toInt()
//                        }
                        }
                    }
                }
            }
        }catch (e:Exception) {
            logger.e("排序错误---->",e)
            logger.d("o1: $o1 o2: $o2")
            return 1
        }
    }

    /**
     * 比较priority的值   当o1大于o2 返回1 小于返回-1 否则返回0
     */
    private fun comparePriority(o1: SymbolInfo, o2: SymbolInfo): Int {
        //如果o1的最小大于o2的最小,说明o2优先级再前面
        if (getMinPriorityLevel(o1) > getMinPriorityLevel(o2)) {
            return 1
        }else if (getMinPriorityLevel(o1) < getMinPriorityLevel(o2)) {
            return -1
        }else {
            //当o1 o2的优先级一样,那么比较DAY>H12>H4
            if (comparePriorityLevel(o1, o2) >= 1) {
                return 1
            }else if (comparePriorityLevel(o1, o2) <= -1){
                return -1
            }else {
                //当级别和类别都相同,比较k线数
                if (comparePriorityNum(o1, o2) >= 1) {
                    return 1
                }else if (comparePriorityNum(o1, o2) <= -1) {
                    return -1
                }else {
                    return 0
                }
            }
        }
    }

    /**
     * 比较priority对象等级   当o1等级大于o2 返回-1 小于返回1 否则返回0   day>12h>4h
     */
    private fun comparePriorityLevel(o1: SymbolInfo, o2: SymbolInfo): Int {

        var o1PrioritySetH4 = PrioritySetConstant.getSetLevelInDiffType(o1.prioritySetH4)
        var o1PrioritySetH12 = PrioritySetConstant.getSetLevelInDiffType(o1.prioritySetH12)
        var o1PrioritySetDay = PrioritySetConstant.getSetLevelInDiffType(o1.prioritySetDay)

        var o2PrioritySetH4 = PrioritySetConstant.getSetLevelInDiffType(o2.prioritySetH4)
        var o2PrioritySetH12 = PrioritySetConstant.getSetLevelInDiffType(o2.prioritySetH12)
        var o2PrioritySetDay = PrioritySetConstant.getSetLevelInDiffType(o2.prioritySetDay)

        var o1Array = arrayListOf(o1PrioritySetDay, o1PrioritySetH12, o1PrioritySetH4)
        var o2Array = arrayListOf(o2PrioritySetDay, o2PrioritySetH12, o2PrioritySetH4)

        return comparePrioritySetLevel(o1Array, o2Array)
    }


    /**
     * 获取对象中H4,H12,DAY中最小一级
     */
    private fun getMinPriorityLevel(symbolino: SymbolInfo): Int {
        var prioritySetH4 = PrioritySetConstant.getSetLevelInDiffType(symbolino.prioritySetH4)
        var prioritySetH12 = PrioritySetConstant.getSetLevelInDiffType(symbolino.prioritySetH12)
        var prioritySetDay = PrioritySetConstant.getSetLevelInDiffType(symbolino.prioritySetDay)
        var minLevel = Int.MAX_VALUE
        if (prioritySetH4 < prioritySetH12) {
            minLevel = prioritySetH4
        }else {
            minLevel = prioritySetH12
        }
        if (minLevel > prioritySetDay) {
            minLevel = prioritySetDay
        }

        return minLevel
    }

    /**
     * 比较两个对象数组,相同级别下,Day > H12 > H4
     */
    private fun comparePrioritySetLevel(array1: ArrayList<Int>, array2: ArrayList<Int>):Int {
        var newArray1 = mutableListOf<Int>()
        var newArray2 = mutableListOf<Int>()
        for (index in 0 until array1.size){
            if (array1.get(index) !=  array2.get(index)) {
                newArray1.add(array1.get(index))
                newArray2.add(array2.get(index))
            }
        }
        if (newArray1.size == 0 && newArray2.size == 0) {
            return 0
        }else{
            val index1 = getArrayMinValueIndex(array1)
            val index2 = getArrayMinValueIndex(array2)
            if (index1 > index2) {
                return 1
            }else{
                return -1
            }
        }
    }

    /**
     * 获取数组中最小的下标
     */
    fun getArrayMinValueIndex(array: ArrayList<Int>): Int {
        var value = Int.MAX_VALUE
        var index = 0
        for (i in 0 until array.size){
            if (array.get(i) < value) {
                value = array.get(i)
                index = i
            }
        }
        return index
    }

    fun comparePriorityNum(o1: SymbolInfo, o2: SymbolInfo): Int {
        var priorityLevel = getMinPriorityLevel(o1)
        var prioritySetH4 = PrioritySetConstant.getSetLevelInDiffType(o1.prioritySetH4)
        var prioritySetH12 = PrioritySetConstant.getSetLevelInDiffType(o1.prioritySetH12)
        var prioritySetDay = PrioritySetConstant.getSetLevelInDiffType(o1.prioritySetDay)

        var o1Num = 999
        var o2Num = 999
        if (priorityLevel == prioritySetDay) {
            o1Num = PriorityNumConstant.getPriorityNumByLevel(priorityLevel, o1.priorityNumDay)
            o2Num = PriorityNumConstant.getPriorityNumByLevel(priorityLevel, o2.priorityNumDay)
        }else if (priorityLevel == prioritySetH12) {
            o1Num = PriorityNumConstant.getPriorityNumByLevel(priorityLevel, o1.priorityNumH12)
            o2Num = PriorityNumConstant.getPriorityNumByLevel(priorityLevel, o2.priorityNumH12)

        }else if (priorityLevel == prioritySetH4){
            o1Num = PriorityNumConstant.getPriorityNumByLevel(priorityLevel, o1.priorityNumH4)
            o2Num = PriorityNumConstant.getPriorityNumByLevel(priorityLevel, o2.priorityNumH4)

        }
        if (o1Num > o2Num) {
            return 1
        }else if (o1Num < o2Num) {
            return -1
        }else {
            return 0
        }
    }
}
